﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
namespace Xww.LCV.Model {
    public class ProbabilityVetexDict : VetexDict {
        
        public List<string> Motifs { get; private set; }
        public double ProbDrop { get; private set; }
        public double Alpha { get; private set; }

        public int MinSpan { get; private set; }
        public int MaxSpan { get; private set; }
        public bool IsDiscrete { get; private set; }


        public ProbabilityVetexDict(double probDrop, double alpha, int minSpan, int maxSpan, bool isDiscrete) {
            this.ProbDrop = probDrop;
            this.Alpha = alpha;
            this.MinSpan = minSpan;
            this.MaxSpan = maxSpan;
            this.IsDiscrete = isDiscrete;
        }
        public ProbabilityVetexDict() : this(0.9, 0.2, 4, int.MaxValue, false) { }

        #region Extract motifs

        public override IList<LCS> ExtractMotifs(IEnumerable<SequencePath> listPaths) {
            Motifs = new List<string>();
            noMotifs = new List<string>();
            foreach (SequencePath item in listPaths) {
                for (int span = MinSpan; span <= MaxSpan; span++) {
                    if (span > item.Count) { break; }    // 如果跨度比序列长度还大，则跳出当前序列循环
                    processSequence(item, span);
                }
            }
            List<LCS> rst = new List<LCS>(Motifs.Count);
            Motifs.ForEach(o => rst.Add((LCS)o));
            return rst;
        }
        List<string> noMotifs = null;
        private void processSequence(SequencePath sequence, int span) {
            int length = sequence.Count;
            if (span < 4 || span > length) { return; }
            var node = sequence.First;
            for (int offset = 0; offset <= length - span; offset++) {
                var first = node;
                var last = first.OffsetNext(span - 1);
                string concat = first.Next.ConcatString(last.Previous, IsDiscrete);

                node = node.Next;
                if (Motifs.Contains(concat)) { continue; }
                //if (noMotifs.Contains(concat)) { continue; }
                if (IsMotif(first, last, span)) {
                    Motifs.Add(concat);
                }
                //else {
                //    noMotifs.Add(concat);
                //}
            }
        }

        bool IsMotif(LinkedListNode<string> first, LinkedListNode<string> last, int span) {
            if (IsDiscrete) {
                return IsMotifDiscrete(first, last, span);
            }
            else {
                return IsMotifConsecutive(first, last, span);
            }
        }



        //此函数用于检测中间为空位的组合 
        private bool IsMotifDiscrete(LinkedListNode<string> first, LinkedListNode<string> last, int span) {
            List<LinkedListNode<string>> currentNodes = null;
            List<LinkedListNode<string>> firstNodes, firstOneNodes, firstTwoNodes, lastNodes, lastOneNodes, lastTwoNodes;
            firstNodes = firstOneNodes = firstTwoNodes = lastNodes = lastOneNodes = lastTwoNodes = null;

            int all_r, all_l, r_1, r_2, l_1, l_2;

            var specificNodes = new LinkedListNode<string>[] { first, first.Next, last, last.Previous };
            //Right
            //int pos = 0;
            var node = first.Next;
            currentNodes = this[node.Value];
            while (node != last) {
                if (specificNodes.Contains(node)) {    // 如果是起始或结束的两位，才需要检测
                    currentNodes = currentNodes.Where(o => o != null && o.Value == node.Value).ToList();
                }
                else { // 中间空位无需检测，节点内容是否吻合。
                    currentNodes = currentNodes.Where(o => o != null).ToList();
                }

                if (node == last.Previous) { lastOneNodes = currentNodes; }
                if (node == last.Previous.Previous) { lastTwoNodes = currentNodes; }

                currentNodes = currentNodes.Select(o => o.Next).ToList();
                node = node.Next;
            }
            lastNodes = currentNodes.Where(o => o.Value == last.Value).ToList();

            all_r = lastNodes.Count;
            r_1 = lastOneNodes.Count; r_2 = lastTwoNodes.Count;
            // Left
            node = last.Previous;
            currentNodes = this[node.Value];
            while (node != first) {
                if (specificNodes.Contains(node)) {    // 如果是起始或结束的两位，才需要检测
                    currentNodes = currentNodes.Where(o => o != null && o.Value == node.Value).ToList();
                }
                else {// 中间空位无需检测，节点内容是否吻合。
                    currentNodes = currentNodes.Where(o => o != null).ToList();
                }

                if (node == first.Next) { firstOneNodes = currentNodes; }
                if (node == first.Next.Next) { firstTwoNodes = currentNodes; }

                currentNodes = currentNodes.Select(o => o.Previous).ToList();
                node = node.Previous;
            }
            firstNodes = currentNodes.Where(o => o.Value == first.Value).ToList();
            all_l = firstNodes.Count;
            l_1 = firstOneNodes.Count; l_2 = firstTwoNodes.Count;

            double dR = 1.0 * all_r / r_1 * r_2 / r_1;
            double dL = 1.0 * all_l / l_1 * l_2 / l_1;
            double average = (dR + dL) / 2;
            //test
            bool rst = dR < this.ProbDrop && dL < this.ProbDrop;
            return rst;
        }

        //此函数用于检测连续的LCV组合 
        private bool IsMotifConsecutive(LinkedListNode<string> first, LinkedListNode<string> last, int span) {
            List<LinkedListNode<string>> currentNodes = null;
            List<LinkedListNode<string>> firstNodes, firstOneNodes, firstTwoNodes, lastNodes, lastOneNodes, lastTwoNodes;
            firstNodes = firstOneNodes = firstTwoNodes = lastNodes = lastOneNodes = lastTwoNodes = null;

            int all_r, all_l, r_1, r_2, l_1, l_2;

            //Right
            //int pos = 0;
            var node = first.Next;
            currentNodes = this[node.Value];
            while (node != last) {
                currentNodes = currentNodes.Where(o => o.Value == node.Value).ToList();

                if (node == last.Previous) { lastOneNodes = currentNodes; }
                if (node == last.Previous.Previous) { lastTwoNodes = currentNodes; }

                currentNodes = currentNodes.Select(o => o.Next).ToList();
                node = node.Next;
            }
            lastNodes = currentNodes.Where(o => o.Value == last.Value).ToList();

            all_r = lastNodes.Count;
            r_1 = lastOneNodes.Count; r_2 = lastTwoNodes.Count;
            // Left
            node = last.Previous;
            currentNodes = this[node.Value];
            while (node != first) {
                currentNodes = currentNodes.Where(o => o.Value == node.Value).ToList();

                if (node == first.Next) { firstOneNodes = currentNodes; }
                if (node == first.Next.Next) { firstTwoNodes = currentNodes; }

                currentNodes = currentNodes.Select(o => o.Previous).ToList();
                node = node.Previous;
            }
            firstNodes = currentNodes.Where(o => o.Value == first.Value).ToList();
            all_l = firstNodes.Count;
            l_1 = firstOneNodes.Count; l_2 = firstTwoNodes.Count;

            double dR = 1.0 * all_r / r_1 * r_2 / r_1;
            double dL = 1.0 * all_l / l_1 * l_2 / l_1;
            double average = (dR + dL) / 2;
            return dR < this.ProbDrop && dL < this.ProbDrop;
        }


        #endregion
    }
}
*/